package com.ruoyi.member.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.ruoyi.common.constant.CacheNames;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.bo.SyncUserBo;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.vo.MemberInfoVo;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.service.UserCommonService;
import com.ruoyi.common.enums.UserBusinessSubType;
import com.ruoyi.common.enums.UserBusinessType;
import com.ruoyi.common.enums.UserType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.redis.CacheUtils;
import com.ruoyi.member.domain.MemberInfo;
import com.ruoyi.member.domain.bo.MemberInfoBo;
import com.ruoyi.member.mapper.MemberInfoMapper;
import com.ruoyi.member.service.IMemberInfoService;
import com.ruoyi.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 工作人员Service业务层处理
 *
 * @author strongme
 * @date 2023-04-25
 */
@RequiredArgsConstructor
@Service
public class MemberInfoServiceImpl implements IMemberInfoService, UserCommonService<MemberInfoBo> {

    private final MemberInfoMapper baseMapper;
    private final ISysUserService userService;

    public void renderSysUserInfo(List<MemberInfoVo> memberInfoVoList) {
        memberInfoVoList = memberInfoVoList.stream().filter(d->!Objects.isNull(d)).collect(Collectors.toList());
        List<Long> businessIds = memberInfoVoList.stream().map(MemberInfoVo::getId).collect(Collectors.toList());
        if(CollUtil.isEmpty(businessIds)) return;
        List<SysUser> syncUserBoList = userService.listUserByBusinessIds(businessIds);
        Map<Long, SysUser> userMapByBusinessId = syncUserBoList.stream().collect(Collectors.toMap(SysUser::getBusinessId, user -> user));
        memberInfoVoList.forEach(memberInfoVo -> {
            memberInfoVo.setSysUser(userMapByBusinessId.get(memberInfoVo.getId()));
        });
    }

    /**
     * 查询工作人员
     */
    @Override
    @Cacheable(value = CacheNames.USER_MEMBER, key = "#id")
    public MemberInfoVo queryById(Long id) {
        MemberInfoVo result = baseMapper.selectVoById(id);
        renderSysUserInfo(Lists.newArrayList(result));
        return result;
    }

    /**
     * 查询工作人员列表
     */
    @Override
    public TableDataInfo<MemberInfoVo> queryPageList(MemberInfoBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<MemberInfo> lqw = buildQueryWrapper(bo);
        Page<MemberInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        renderSysUserInfo(result.getRecords());
        return TableDataInfo.build(result);
    }

    /**
     * 查询工作人员列表
     */
    @Override
    public List<MemberInfoVo> queryList(MemberInfoBo bo) {
        LambdaQueryWrapper<MemberInfo> lqw = buildQueryWrapper(bo);
        List<MemberInfoVo> result = baseMapper.selectVoList(lqw);
        renderSysUserInfo(result);
        return result;
    }

    private LambdaQueryWrapper<MemberInfo> buildQueryWrapper(MemberInfoBo bo) {
        LambdaQueryWrapper<MemberInfo> lqw = Wrappers.lambdaQuery();
        if (bo.getSubType() != null && CollUtil.isNotEmpty(bo.getSubType().getMemberTypeList())) {
            lqw.in(MemberInfo::getType, bo.getSubType().getMemberTypeList());
        }
        if (bo.getSubTypeList() != null && CollUtil.isNotEmpty(bo.getSubTypeList())) {
            List<String> types = Lists.newArrayList();
            bo.getSubTypeList().forEach(subType -> {
                types.addAll(subType.getMemberTypeList());
            });
            lqw.in(MemberInfo::getType, types);
        }
        lqw.eq(StringUtils.isNotBlank(bo.getType()), MemberInfo::getType, bo.getType());
        lqw.like(StringUtils.isNotBlank(bo.getGxqy()), MemberInfo::getGxqy, bo.getGxqy());
        lqw.like(StringUtils.isNotBlank(bo.getName()), MemberInfo::getName, bo.getName());
        lqw.eq(StringUtils.isNotBlank(bo.getGzzw()), MemberInfo::getGzzw, bo.getGzzw());
        lqw.eq(StringUtils.isNotBlank(bo.getMobile()), MemberInfo::getMobile, bo.getMobile());
        lqw.eq(StringUtils.isNotBlank(bo.getGender()), MemberInfo::getGender, bo.getGender());
        lqw.eq(StringUtils.isNotBlank(bo.getXznzw()), MemberInfo::getXznzw, bo.getXznzw());
        lqw.eq(StringUtils.isNotBlank(bo.getFgqk()), MemberInfo::getFgqk, bo.getFgqk());
        lqw.eq(StringUtils.isNotBlank(bo.getZzmm()), MemberInfo::getZzmm, bo.getZzmm());
        lqw.eq(StringUtils.isNotBlank(bo.getWhcd()), MemberInfo::getWhcd, bo.getWhcd());
        lqw.eq(StringUtils.isNotBlank(bo.getIdno()), MemberInfo::getIdno, bo.getIdno());
        lqw.eq(StringUtils.isNotBlank(bo.getAddress()), MemberInfo::getAddress, bo.getAddress());
        lqw.eq(StringUtils.isNotBlank(bo.getUnit()), MemberInfo::getUnit, bo.getUnit());
        lqw.eq(StringUtils.isNotBlank(bo.getSgjb()), MemberInfo::getSgjb, bo.getSgjb());
        lqw.eq(StringUtils.isNotBlank(bo.getImages()), MemberInfo::getImages, bo.getImages());
        return lqw;
    }

    /**
     * 新增工作人员
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByBo(MemberInfoBo bo) {
        MemberInfo add = BeanUtil.toBean(bo, MemberInfo.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        // 绑定或解绑系统用户
        userService.bindUser(bo.getId(), bo.getSysUserId());
        return flag;
    }

    /**
     * 修改工作人员
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = CacheNames.USER_MEMBER, key = "#bo.id", condition = "#bo.id != null")
    public Boolean updateByBo(MemberInfoBo bo) {
        MemberInfo update = BeanUtil.toBean(bo, MemberInfo.class);
        validEntityBeforeSave(update);
        // 绑定或解绑系统用户
        userService.bindUser(bo.getId(), bo.getSysUserId());
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(MemberInfo entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除工作人员
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        ids.forEach(id -> {
            CacheUtils.evict(CacheNames.USER_MEMBER, id);
        });
        userService.deleteUserByBusinessIds(ids);
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public SyncUserBo extractUserBo(MemberInfoBo userObj) {
        SyncUserBo syncUserBo = BeanUtil.toBean(userObj, SyncUserBo.class);
        syncUserBo.setMobile(userObj.getMobile());
        syncUserBo.setUserType(UserType.SYS_USER.getUserType());
        syncUserBo.setBusinessType(UserBusinessType.USER_MEMBER);
        syncUserBo.setBusinessSubType(UserBusinessSubType.getUserType(userObj.getType(), UserBusinessType.USER_MEMBER));
        syncUserBo.setBusinessId(userObj.getId());
        return syncUserBo;
    }
}
